The initial goal of the seeker project is to create a graphic object that can identify the location of another object on screen and move towards it. I started it to help me learn Silverlight. Hopefully it can help you as well.

Concepts covered at a very simple level are:
-	Publishing and consuming events
-	Programmatically adding and positioning controls on a page
-	Drag and drop
-	Animation / Storyboard
-	Calculating distance onscreen

Events constantly attract our attention in the real-world, so I designed seeker to become aware of objects as the result of events. In the seeker world, a SightingEvent is broadcast whenever a colored rectangle is dragged and dropped on the screen. Every seeker in existence becomes aware of that event because every seeker subscribes to the SightingEvent. Not only does the seeker know of the event, but it also knows precisely where it occurred, because along with the event it gets a SightingEventArgs object which contains the screen coordinates of the drop point.

That gives you the basic idea, so let's forget about events for a moment and talk about getting objects on the page. Through the Blend UI, I added a green rectangle to be the target of the seekers' attention. It can be moved around though drag-and-drop.

Since the seeker needs to have some smarts to do something about the target, I made it a User Control. At this point, the graphic representation is just a TextBox that can show the name of the individual seeker. But it could be anything you wanted the user control to show. I added one seeker object through the Blend UI and two others programmatically, which you can see in the MainPage_Loaded event handler in MainPage.xaml.cs. I point out there, and here, that the position parameter to seeker1.SetValue(Canvas.LeftProperty, 300.0); and the like must be a double.

Now that we have the players on the stage, let's look at what seeker does when it receives a SightingEvent. What it does is to start moving towards the sighting point that it received in the SightingEventArgs object received with the event. So first, it has to detect the direction of the event ... oh, wait, no it doesn't, an animation does it automatically. Just look at the MoveTo method in Seeker.xaml.cs to see how easy it is. MoveTo is pretty straightforward, so I won't describe it further - I didn't really write it, I just filed off the serial numbers.

Speaking of MoveTo, one of the parameters is duration. Right now, I just want the seeker to move at a consistent speed no matter how near or how far the target. To do that we have to determine the distance. A little excursion down memory lane tells us that the length of the hypotenuse of a triangle is equal to the square root of the sum of the square of the opposite two sides, so we can determine the straight line distance by taking the square root of the sum of the vertical distance squared and the horizontal distance squared.

That's the idea anyway, I'm pretty sure of my theory, but I'm a little dubious about my execution. I experimented with the number of cells per second I expected my seeker to cross, but the number I ended up using, 100, seems too high when compared with results. I'll be looking into that further.

Anyway, the distance calculation in c# is pretty heavily commented in the HandleSightingEvent method in Seeker.xaml.cs if you're interested.

I couldn't really explain the drag-and-drop code any more clearly than the code does. It's lifted straight from MSDN.

The rest is pretty self explanatory other than the event handling, so I'll discuss that briefly.

Publishing events is really pretty easy. It's the syntax that makes it difficult. I'm just going to describe what the various components do without getting into syntax too much.

 - Define a custom EventArgs class.

	public class SightingEventArgs : EventArgs

When you want to broadcast SightingEvent, create a SightingEventArgs object to be sent when the event is broadcast.	See SightingEvent.cs for the class definition.

The following elements of the event are all coded in the sender / publisher of the event, in this case MainPage.

- Define the signature of a method required to subscribe to the event.

	public delegate void SightingEventHandler(object sender, SightingEventArgs e)

 - Define an event 'broadcaster' that sends events by making calls to methods that match the SightEventHandler signature.

	public event SightingEventHandler SightingEvent;

 - Add a subscriber to the event. Note that strictly speaking it's the method that subscribes, not the object, SightingEvent has no knowledge of the subscribing object

	SightingEvent += this.seeker1.HandleSightingEvent;

- Broadcast the event to all subscribers, 'this' is the event sender, 'e' is an instance of SightingEventArgs. I'd prefer 'args', but 'e' is more standard.

	SightingEvent(this, e);

If you don't get hung up on the semantics of the 'event' keyword it all pretty much makes sense; I think the event keyword would more logically be eventBroadcaster.

To consume the event, define a method on the subscriber that matches the signature defined by the SightingEventHandler delegate:

	public void HandleSightingEvent(object sender, SightingEventArgs e)

That's it! When you want to broadcast a SightingEvent, create a SightingEventArgs object and call SightingEvent to send it out to all subscribers.

